package com.punch.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.punch.common.constant.CommonConstant;
import com.punch.common.dto.user.user.PasswordDTO;
import com.punch.common.dto.user.user.RedisUserDTO;
import com.punch.common.dto.user.user.UserDTO;
import com.punch.common.dto.user.user.UserOrganAuditDTO;
import com.punch.common.enums.user.role.UserRoleEnum;
import com.punch.common.enums.user.user.AuditStatusEnum;
import com.punch.common.enums.user.user.UserTypeEnum;
import com.punch.common.exception.BusinessException;
import com.punch.common.feign.FeignAreaService;
import com.punch.common.feign.FeignClassService;
import com.punch.common.model.LoginUser;
import com.punch.common.model.SysMenu;
import com.punch.common.page.PageInfo;
import com.punch.common.query.user.user.UserQueryInfo;
import com.punch.common.service.impl.SuperServiceImpl;
import com.punch.common.simple.redis.utils.RedisUtil;
import com.punch.common.simple.redis.utils.UserUtil;
import com.punch.common.tools.BasePage;
import com.punch.common.utils.ImageUtil;
import com.punch.common.utils.PhoneUtils;
import com.punch.common.vo.course.report.CourseReportVO;
import com.punch.common.vo.course.report.OrganReportVO;
import com.punch.common.vo.user.menu.UserMenuTreeVO;
import com.punch.common.vo.user.user.*;
import com.punch.user.exception.UserExceptionEnum;
import com.punch.user.mapper.SysUserMapper;
import com.punch.user.model.*;
import com.punch.user.service.*;
import com.punch.user.util.MenuUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author 作者 owen E-mail: 624191343@qq.com
 */
@Slf4j
@Service
public class UserServiceImpl extends SuperServiceImpl<SysUserMapper, SysUser> implements UserService {

    @Resource
    private UserOrganService userOrganService;

    @Resource
    private UserSchoolService userSchoolService;

    @Resource
    private RoleUserService roleUserService;

    @Resource
    private RoleMenuService roleMenuService;

    @Resource
    private MenuService menuService;

    @Resource
    private AuditLogService auditLogService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private FeignAreaService feignAreaService;

    @Resource
    private FeignClassService feignClassService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SupplierService supplierService;

    @Resource
    private StudentService studentService;

    @Resource
    private TeacherService teacherService;


    /**
     * 超级管理员/运营人员用户分页
     *
     * @param queryInfo 查询条件
     * @return PageInfo<UserPageVO>
     */
    @Override
    public PageInfo<UserPageVO> queryPage(UserQueryInfo queryInfo) {
        //管理员查看所有数据
        return BasePage.queryBasePage(queryInfo, params -> baseMapper.queryCount(params),
                params -> baseMapper.queryList(params));
    }

    /**
     * 机构用户分页信息
     *
     * @param queryInfo 查询条件
     * @return PageInfo<UserPageVO>
     */
    @Override
    public PageInfo<UserPageVO> listOrganUser(UserQueryInfo queryInfo) {
        //超级管理员
        //教育局只查看已提交审核与审核成功
        if (queryInfo.getCurrentRoleId() == UserRoleEnum.EDUCATION.getCode()) {
            queryInfo.setAuditType(0);
        }
        //机构
        if (queryInfo.getCurrentRoleId() == UserRoleEnum.ORGAN.getCode()) {
            queryInfo.setCreateId(UserUtil.getLoginUserId());
        }
        return BasePage.queryBasePage(queryInfo, params -> baseMapper.queryCount(params),
                params -> baseMapper.queryList(params));
    }

    /**
     * 学校用户分页信息
     *
     * @param queryInfo 查询条件
     * @return PageInfo<UserPageVO>
     */
    @Override
    public PageInfo<UserPageVO> listSchoolUser(UserQueryInfo queryInfo) {
        return BasePage.queryBasePage(queryInfo, params -> baseMapper.querySchoolCount(params),
                params -> baseMapper.querySchoolList(params));
    }

    /**
     * 新增用户
     *
     * @param userDTO 用户表单
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveUser(UserDTO userDTO) {
        //一个地区下只有一个教育局
        if (userDTO.getRoleId() == UserRoleEnum.EDUCATION.getCode()) {
            //查找是否已经添加过教育局
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUser::getRoleId, userDTO.getRoleId()).eq(SysUser::getAreaId, userDTO.getAreaId());
            if (count(queryWrapper) > 0) {
                throw new BusinessException(UserExceptionEnum.AREA_ONLY_ONE_EDUCATION);
            }
        }
        //如果当前是运营人员,添加的运营人员只能为子地区的运营人员
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        if (loginUser.getRoleId() == UserRoleEnum.MANAGER.getCode() && userDTO.getRoleId() == UserRoleEnum.MANAGER.getCode()) {
            if (loginUser.getAreaId().equals(userDTO.getAreaId())) {
                throw new BusinessException(UserExceptionEnum.ORG_ONLY_ADD_CHILD);
            }
        }

        verifyMobile(userDTO.getMobile());
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userDTO, sysUser);
        //处理头像
        if (StrUtil.isNotEmpty(userDTO.getHeadImgUrl())) {
            sysUser.setHeadImgUrl(ImageUtil.removePrefix(userDTO.getHeadImgUrl()));
        }
        verifyAccount(sysUser.getMobile(), 0L);
        sysUser.setPassword(passwordEncoder.encode(userDTO.getMobile()));
        //如果是机构设置为待审核状态
        if (userDTO.getRoleId() == UserRoleEnum.ORGAN.getCode()) {
            sysUser.setAuditStatus(AuditStatusEnum.TO_AUDIT.getCode());
        }
        sysUser.setRoleName(UserRoleEnum.getName(userDTO.getRoleId()));
        Integer areaId = userDTO.getAreaId();
        String parentIds = feignAreaService.getParentIds(areaId);
        sysUser.setAllAreaIds(parentIds + "," + areaId);
        boolean flag = save(sysUser);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.DATA_INSERT_EXCEPTION);
        }
        //学校
        if (userDTO.getRoleId() == UserRoleEnum.SCHOOL.getCode()) {
            SysUserSchool sysUserSchool = new SysUserSchool();
            BeanUtils.copyProperties(userDTO.getUserExtendVO(), sysUserSchool);
            sysUserSchool.setUserId(sysUser.getId());
            flag = userSchoolService.save(sysUserSchool);
            if (!flag) {
                throw new BusinessException(UserExceptionEnum.SCHOOL_INSERT_EXCEPTION);
            }
            //插入供应商
            SysSupplier sysSupplier = new SysSupplier();
            sysSupplier.setBankAccount(sysUserSchool.getBankAccount());
            sysSupplier.setBankOpen(sysUserSchool.getBankOpen());
            sysSupplier.setBankUserName(sysUserSchool.getBankUserName());
            sysSupplier.setUserId(sysUser.getId());
            sysSupplier.setSupplierName(userDTO.getUsername());
            supplierService.save(sysSupplier);
        }
        //机构
        if (userDTO.getRoleId() == UserRoleEnum.ORGAN.getCode()) {
            SysUserOrgan sysUserOrgan = new SysUserOrgan();
            BeanUtils.copyProperties(userDTO.getUserExtendVO(), sysUserOrgan);
            //生成编号
            sysUserOrgan.setOrgNo(generateOrderNo());
            sysUserOrgan.setUserId(sysUser.getId());
            flag = userOrganService.save(sysUserOrgan);
            if (!flag) {
                throw new BusinessException(UserExceptionEnum.ORG_INSERT_EXCEPTION);
            }
            //插入供应商
            SysSupplier sysSupplier = new SysSupplier();
            sysSupplier.setBankUserName(sysUserOrgan.getBankUserName());
            sysSupplier.setBankAccount(sysUserOrgan.getBankAccount());
            sysSupplier.setBankOpen(sysUserOrgan.getBankOpen());
            sysSupplier.setUserId(sysUser.getId());
            sysSupplier.setSupplierName(userDTO.getUsername());
            supplierService.save(sysSupplier);
        }
        //插入用户角色关系表
        SysRoleUser sysRoleUser = new SysRoleUser();
        sysRoleUser.setUserId(sysUser.getId());
        sysRoleUser.setRoleId(userDTO.getRoleId());
        roleUserService.save(sysRoleUser);
        return sysUser.getId();
    }

    /**
     * 修改用户
     *
     * @param userDTO 用户表单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UserDTO userDTO) {
        verifyMobile(userDTO.getMobile());
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userDTO, sysUser);
        //处理头像
        if (StrUtil.isNotEmpty(userDTO.getHeadImgUrl())) {
            sysUser.setHeadImgUrl(ImageUtil.removePrefix(userDTO.getHeadImgUrl()));
        }
        verifyAccount(sysUser.getMobile(), userDTO.getUserId());
//        sysUser.setPassword(passwordEncoder.encode(userDTO.getMobile()));
        sysUser.setId(userDTO.getUserId());
        boolean flag = updateById(sysUser);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        //学校
        if (userDTO.getRoleId() == UserRoleEnum.SCHOOL.getCode()) {
            //查找原先的学校添加学生方式
            QueryWrapper<SysUserSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUserSchool::getUserId, userDTO.getUserId());
            SysUserSchool sysUserSchoolEX = userSchoolService.getOne(queryWrapper);
            Optional.ofNullable(sysUserSchoolEX).orElseThrow(() -> new BusinessException(UserExceptionEnum.USER_NOT_EXIST));
            //添加学生由家长APP端添加修改成学校PC端添加,需要把该学校下的所有数据都是删除了
            if (sysUserSchoolEX.getAddStuType() == 1 && userDTO.getUserExtendVO().getAddStuType() == 0) {
                //删除学生表
                UpdateWrapper<SysStudent> deleteStudentWrapper = new UpdateWrapper<>();
                deleteStudentWrapper.lambda().eq(SysStudent::getCreateId, userDTO.getUserId());
                studentService.remove(deleteStudentWrapper);
                //删除家长关联学生表
                // TODO: 2020/12/5
            }

            SysUserSchool sysUserSchool = new SysUserSchool();
            BeanUtils.copyProperties(userDTO.getUserExtendVO(), sysUserSchool);
            sysUserSchool.setId(sysUserSchoolEX.getId());
            userSchoolService.updateById(sysUserSchool);
            //修改供应商账号信息
            supplierService.updateSupplierWithUser(userDTO.getUserId(), userDTO.getRoleId());
        }
        //机构
        if (userDTO.getRoleId() == UserRoleEnum.ORGAN.getCode()) {
            SysUserOrgan sysUserOrgan = new SysUserOrgan();
            //结算信息
            if (userDTO.getUserExtendVO() != null) {
                BeanUtils.copyProperties(userDTO.getUserExtendVO(), sysUserOrgan);
            }
            //资质信息
            if (userDTO.getOrgCertificationVO() != null) {
                //打印凭证
                if (StrUtil.isNotEmpty(userDTO.getOrgCertificationVO().getVoucherUrl())) {
                    sysUserOrgan.setVoucherUrl(ImageUtil.removePrefix(userDTO.getOrgCertificationVO().getVoucherUrl()));
                } else {
                    sysUserOrgan.setVoucherUrl("");
                }
                //许可证
                if (StrUtil.isNotEmpty(userDTO.getOrgCertificationVO().getLicenceUrl())) {
                    sysUserOrgan.setLicenceUrl(ImageUtil.removePrefix(userDTO.getOrgCertificationVO().getLicenceUrl()));
                } else {
                    sysUserOrgan.setLicenceUrl("");
                }
                //身份证
                if (StrUtil.isNotEmpty(userDTO.getOrgCertificationVO().getIdCardUrl())) {
                    sysUserOrgan.setIdCardUrl(ImageUtil.removePrefix(userDTO.getOrgCertificationVO().getIdCardUrl()));
                } else {
                    sysUserOrgan.setIdCardUrl("");
                }
                //营业执照
                if (StrUtil.isNotEmpty(userDTO.getOrgCertificationVO().getBusinessLicenseUrl())) {
                    sysUserOrgan.setBusinessLicenseUrl(ImageUtil.removePrefix(userDTO.getOrgCertificationVO().getBusinessLicenseUrl()));
                } else {
                    sysUserOrgan.setBusinessLicenseUrl("");
                }
            }
            UpdateWrapper<SysUserOrgan> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(SysUserOrgan::getUserId, userDTO.getUserId());
            userOrganService.update(sysUserOrgan, updateWrapper);
            //修改供应商账号信息
            supplierService.updateSupplierWithUser(userDTO.getUserId(), userDTO.getRoleId());
        }
    }


    /**
     * 获取用户信息
     *
     * @param userId 用户uid
     * @param type   0-管理员 1-其他角色
     * @return UserVO
     */
    @Override
    public UserVO getUser(Long userId, Integer type) {
        SysUser sysUser = getById(userId);
        if (sysUser == null) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(sysUser, userVO);
        //处理头像
        if (StrUtil.isNotEmpty(sysUser.getHeadImgUrl())) {
            userVO.setHeadImgUrl(ImageUtil.addPrefix(sysUser.getHeadImgUrl()));
        }
        userVO.setUserId(userId);
        //如果该用户信息是机构,需要查看机构扩展信息
        if (sysUser.getRoleId() == UserRoleEnum.ORGAN.getCode()) {
            //如果是机构与教育局 只能看到资质信息
            QueryWrapper<SysUserOrgan> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUserOrgan::getUserId, userId);
            SysUserOrgan userOrgan = userOrganService.getOne(queryWrapper);
            if (type == 0) {
                UserExtendVO userExtendVO = new UserExtendVO();
                BeanUtils.copyProperties(userOrgan, userExtendVO);
                userVO.setUserExtendVO(userExtendVO);
            }
            OrgCertificationVO orgCertificationVO = new OrgCertificationVO();
            //打印凭证
            if (StrUtil.isNotEmpty(userOrgan.getVoucherUrl())) {
                orgCertificationVO.setVoucherUrl(ImageUtil.addPrefix(userOrgan.getVoucherUrl()));
            }
            //许可证
            if (StrUtil.isNotEmpty(userOrgan.getLicenceUrl())) {
                orgCertificationVO.setLicenceUrl(ImageUtil.addPrefix(userOrgan.getLicenceUrl()));
            }
            //身份证
            if (StrUtil.isNotEmpty(userOrgan.getIdCardUrl())) {
                orgCertificationVO.setIdCardUrl(ImageUtil.addPrefix(userOrgan.getIdCardUrl()));
            }
            //营业执照
            if (StrUtil.isNotEmpty(userOrgan.getBusinessLicenseUrl())) {
                orgCertificationVO.setBusinessLicenseUrl(ImageUtil.addPrefix(userOrgan.getBusinessLicenseUrl()));
            }
            userVO.setOrgCertificationVO(orgCertificationVO);
        }
        //学校信息
        if (sysUser.getRoleId() == UserRoleEnum.SCHOOL.getCode() && type == 0) {
            QueryWrapper<SysUserSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUserSchool::getUserId, userId);
            SysUserSchool userSchool = userSchoolService.getOne(queryWrapper);
            UserExtendVO userExtendVO = new UserExtendVO();
            BeanUtils.copyProperties(userSchool, userExtendVO);
            userVO.setUserExtendVO(userExtendVO);
        }
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditOrgUser(UserOrganAuditDTO userOrganAuditDTO) {
        log.info("机构审核:{}", userOrganAuditDTO);
        Long userId = userOrganAuditDTO.getUserId();
        SysUser sysUserEX = getById(userId);
        Optional.ofNullable(sysUserEX).orElseThrow(() -> new BusinessException(UserExceptionEnum.USER_NOT_EXIST));
        //如果用户不是机构,则不能审核
        if (sysUserEX.getRoleId() != UserRoleEnum.ORGAN.getCode()) {
            throw new BusinessException(UserExceptionEnum.ONLY_ORG_USER_AUDIT);
        }
        verifyStatus(userOrganAuditDTO.getAuditStatus(), sysUserEX.getAuditStatus());
        //如果当前用户是机构,在提交审核需要更新资质信息
        if (AuditStatusEnum.SUBMITTED.getCode() == userOrganAuditDTO.getAuditStatus()) {
            //验证机构的营业执照与身份证是否填写
//            QueryWrapper<SysUserOrgan> queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().eq(SysUserOrgan::getUserId, userOrganAuditDTO.getUserId());
//            SysUserOrgan sysUserOrganEX = userOrganService.getOne(queryWrapper);
//            if (StringUtils.isEmpty(sysUserOrganEX.getBusinessLicenseUrl())) {
//                throw new BusinessException(UserExceptionEnum.ORG_BUSINESS_LICENSE_URL_EMPTY);
//            }
//            if (StringUtils.isEmpty(sysUserOrganEX.getIdCardUrl())) {
//                throw new BusinessException(UserExceptionEnum.ORG_ID_CARD_URL_EMPTY);
//            }
            //如果机构之前没提交则新增，有则修改
            SysUserOrgan sysUserOrgan = new SysUserOrgan();
            BeanUtils.copyProperties(userOrganAuditDTO, sysUserOrgan);
            userOrganService.updateById(sysUserOrgan);
        }
        //如果机构审核成功,则机构提交的教师/课程的状态 机构待审核提交 都修改成 审批中
        if (AuditStatusEnum.PASSED.getCode() == userOrganAuditDTO.getAuditStatus()) {
            //修改教师状态
            teacherService.updateUnAuditCommit(userId);
            //修改课程状态
            feignClassService.updateUnAuditCommit(userId);
            //修改redis中机构数据
            StringBuilder sb = new StringBuilder();
            sb.append(CommonConstant.SECURITY_REDIS_USER_PREFIX).append("webApp:").append(userId);
            RedisUserDTO redisUserDTO = (RedisUserDTO) redisUtil.getValue(sb.toString());
            log.info("redis用户信息:{}", redisUserDTO);
            if (redisUserDTO != null) {
                redisUserDTO.setAuditStatus(AuditStatusEnum.PASSED.getCode());
                log.info("修改以后的redis用户信息:{}", redisUserDTO);
                redisUtil.setValue(sb.toString(), redisUserDTO, 28800L);
            }

        }
        SysUser sysUser = new SysUser();
        sysUser.setId(userOrganAuditDTO.getUserId());
        sysUser.setAuditStatus(userOrganAuditDTO.getAuditStatus());
        updateById(sysUser);
        insertAuditLog(userOrganAuditDTO);
    }

    /**
     * 通过手机号查询用户、角色信息
     *
     * @param mobile 手机号
     */
    @Override
    public LoginUser getUserByMobile(String mobile) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getMobile, mobile);
        SysUser sysUserEX = getOne(queryWrapper);
        if (sysUserEX == null) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(sysUserEX.getId());
        loginUser.setUsername(sysUserEX.getMobile());
        loginUser.setUserShowName(sysUserEX.getUsername());
        loginUser.setEnabled(sysUserEX.getEnabled() == 1);
        loginUser.setPassword(sysUserEX.getPassword());
        //用户信息存放redis中
        StringBuilder sb = new StringBuilder();
        sb.append(CommonConstant.SECURITY_REDIS_USER_PREFIX).append("webApp:").append(sysUserEX.getId());
        RedisUserDTO redisUserDTO = new RedisUserDTO();
        BeanUtils.copyProperties(sysUserEX, redisUserDTO);
        redisUserDTO.setUserId(sysUserEX.getId());
        redisUtil.setValue(sb.toString(), redisUserDTO, 28800L);
        return loginUser;
    }

    /**
     * 获取当前用户菜单
     */
    @Override
    public List<UserMenuTreeVO> getUserMenuTree() {
        Long userId = UserUtil.getLoginUserId();
        SysUser sysUserEX = getById(userId);
        if (sysUserEX == null) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        Integer currentRoleId = sysUserEX.getRoleId();
        //如果是超级管理员
        if (sysUserEX.getRoleId() == UserRoleEnum.ADMIN.getCode()) {
            List<SysMenu> allMenuList = menuService.list();
            Map<Long, List<SysMenu>> menuMap = allMenuList.stream().collect(Collectors.groupingBy(SysMenu::getParentId));
            return MenuUtil.handlerUserMenuTree(menuMap, 0L);
        }
        //如果是机构而且是审批未通过状态
        if (sysUserEX.getRoleId() == UserRoleEnum.ORGAN.getCode() && sysUserEX.getAuditStatus() != AuditStatusEnum.PASSED.getCode()) {
            List<Long> idList = new ArrayList<>();
            //机构
            idList.add(1288080353522900993L);
            idList.add(1288330568400093186L);
            idList.add(1288330955647598593L);
            idList.add(1288330750097342465L);
            //教师管理
            idList.add(1286687087121002497L);
            idList.add(1288316414276583426L);
            idList.add(1288321529695944706L);
            idList.add(1288321589817098242L);
            idList.add(1288321673174695938L);
            //课程管理
            idList.add(1286687188539273217L);
            idList.add(1288330096259874817L);
            idList.add(1288330151528218625L);
            idList.add(1288330222109966337L);
            idList.add(1290494101090885633L);
            idList.add(1290494361720741890L);
            List<SysMenu> menuList = menuService.listByIds(idList);
            Map<Long, List<SysMenu>> menuMap = menuList.stream().collect(Collectors.groupingBy(SysMenu::getParentId));
            return MenuUtil.handlerUserMenuTree(menuMap, 0L);
        }
        //从redis中获取
        List roleMenuIdList = redisUtil.getList("role:" + currentRoleId + ":menuIds", Long.class);
        if (CollUtil.isEmpty(roleMenuIdList)) {
            roleMenuIdList = new ArrayList<>();
            List<SysMenu> allMenuList = menuService.list();
            QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysRoleMenu::getRoleId, currentRoleId);
            List<SysRoleMenu> list = roleMenuService.list(queryWrapper);
            List<Long> menuIdList = new ArrayList<>();
            list.forEach(sysRoleMenu -> menuIdList.add(sysRoleMenu.getMenuId()));
            List<SysMenu> roleMenuList = menuService.listByIds(menuIdList);
            MenuUtil.handUserMenu(allMenuList, roleMenuList, roleMenuIdList);
            redisUtil.leftPushList("role:" + currentRoleId + ":menuIds", roleMenuIdList, UserServiceImpl::apply);
            allMenuList = null;
            list = null;
        }
        List<SysMenu> list = menuService.listByIds(roleMenuIdList);
        Map<Long, List<SysMenu>> menuMap = list.stream().collect(Collectors.groupingBy(SysMenu::getParentId));
        return MenuUtil.handlerUserMenuTree(menuMap, 0L);
    }

    private static Object apply(Object t) {
        return t;
    }

    /**
     * 修改用户密码
     *
     * @param userId      用户uid
     * @param passwordDTO 密码表单
     * @return ''
     */
    @Override
    public String resetPassword(Long userId, PasswordDTO passwordDTO) {
        if (passwordDTO.getPassword().equalsIgnoreCase(passwordDTO.getNewPassword())) {
            throw new BusinessException(UserExceptionEnum.USER_PASSWORD_EQUAL);
        }
        boolean temp = passwordEncoder.matches(passwordDTO.getPassword(), getById(userId).getPassword());
        if (!temp) {
            throw new BusinessException(UserExceptionEnum.USER_OLD_PASSWORD_ERROR);
        }
        SysUser sysUser = new SysUser();
        sysUser.setPassword(passwordEncoder.encode(passwordDTO.getNewPassword()));
        sysUser.setId(userId);
        updateById(sysUser);
        return "";
    }

    /**
     * 用户启用/停用
     *
     * @param userId 用户uid
     */
    @Override
    public void enableUser(Long userId) {
        SysUser sysUserEX = getById(userId);
        if (sysUserEX == null) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        SysUser updateUser = new SysUser();
        //启用变成停用
        if (sysUserEX.getEnabled() == 1) {
            updateUser.setEnabled(0);
        }
        //停用变成启用
        if (sysUserEX.getEnabled() == 0) {
            updateUser.setEnabled(1);
        }
        updateUser.setId(userId);
        updateById(updateUser);
    }

    /**
     * 学校用户分页列表
     *
     * @return List<SimpleSchoolVO>
     */
    @Override
    public List<SimpleSchoolVO> listUserSchool() {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getRoleId, UserRoleEnum.SCHOOL.getCode()).eq(SysUser::getEnabled, 1);
        List<SysUser> list = list(queryWrapper);
        List<SimpleSchoolVO> retList = new ArrayList<>();
        list.forEach(sysUser -> {
            SimpleSchoolVO simpleSchoolVO = new SimpleSchoolVO();
            simpleSchoolVO.setSchoolId(sysUser.getId());
            simpleSchoolVO.setSchoolName(sysUser.getUsername());
            retList.add(simpleSchoolVO);
        });
        return retList;
    }

    /**
     * 获取机构审批失败信息
     *
     * @param userId 用户id/机构id
     * @return string
     */
    @Override
    public String getOrganAuditMessage(Long userId) {
        QueryWrapper<SysAuditLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysAuditLog::getUserId, userId).orderByDesc(SysAuditLog::getUpdateTime).last("limit 1");
        SysAuditLog sysAuditLog = auditLogService.getOne(queryWrapper);
        return sysAuditLog.getRemarks();
    }

    /**
     * 学校下机构数量
     *
     * @return
     */
    @Override
    public List<SchoolOrganResultVO> organReport() {
        List<SysUser> sysUsers = getSchool();
        //统计学校下入驻的机构数量
        List<SchoolOrganResultVO> schoolOrganResultVOS = new ArrayList<>();
        if (CollUtil.isEmpty(sysUsers)) {
            return schoolOrganResultVOS;
        }

        for (SysUser sysUser : sysUsers) {
            //获取学校入驻的机构列表
            List<OrganReportVO> organReportVOS = feignClassService.getOrganCount(sysUser.getId());
            SchoolOrganResultVO schoolOrganResultVO = new SchoolOrganResultVO();
            schoolOrganResultVO.setSchoolName(sysUser.getUsername());
            if (CollUtil.isNotEmpty(organReportVOS)) {
                schoolOrganResultVO.setOrganCount(organReportVOS.size());
                schoolOrganResultVO.setOrganReportVOS(organReportVOS);
            } else {
                schoolOrganResultVO.setOrganCount(0);
            }
            schoolOrganResultVOS.add(schoolOrganResultVO);
        }

//        if (CollUtil.isNotEmpty(schoolOrganResultVOS)) {
//            //使用Collections集合工具类进行排序
//            Collections.sort(schoolOrganResultVOS, new Comparator<SchoolOrganResultVO>() {
//                @Override
//                public int compare(SchoolOrganResultVO item1, SchoolOrganResultVO item2) {
//                    //升序排序，降序反写
//                    return item1.getOrganCount()-item2.getOrganCount();
//                }
//            });
//        }
        return schoolOrganResultVOS;
    }

    /**
     * 学校下开课数
     *
     * @return
     */
    @Override
    public List<SchoolCousreResultVO> courseReport() {
        List<SysUser> sysUsers = getSchool();
        //统计学校下入驻的机构数量
        List<SchoolCousreResultVO> schoolCousreResultVOS = new ArrayList<>();
        if (CollUtil.isEmpty(sysUsers)) {
            return schoolCousreResultVOS;
        }
        for (SysUser sysUser : sysUsers) {
            //获取学校入驻的机构列表
            List<CourseReportVO> courseReportVOS = feignClassService.getCourseCount(sysUser.getId());
            SchoolCousreResultVO schoolCousreResultVO = new SchoolCousreResultVO();
            schoolCousreResultVO.setSchoolName(sysUser.getUsername());
            if (CollUtil.isNotEmpty(courseReportVOS)) {
                schoolCousreResultVO.setCourseCount(courseReportVOS.size());
                schoolCousreResultVO.setCourseReportVOS(courseReportVOS);
            } else {
                schoolCousreResultVO.setCourseCount(0);
            }
        }
        return schoolCousreResultVOS;
    }

    private List<SysUser> getSchool() {
        Integer currentAreaId = UserUtil.getLoginUser().getAreaId();
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda().eq(SysUser::getAreaId, currentAreaId);
        sysUserQueryWrapper.lambda().eq(SysUser::getRoleId, UserRoleEnum.SCHOOL.getCode());
        //统计教育局下的学校列表
        List<SysUser> sysUsers = this.getBaseMapper().selectList(sysUserQueryWrapper);

        return sysUsers;
    }

    /**
     * 重置密码
     *
     * @param userId 用户id
     * @return long
     */
    @Override
    public Long resetPwd(Long userId) {
        SysUser sysUserEX = getById(userId);
        if (sysUserEX == null) {
            throw new BusinessException(UserExceptionEnum.USER_NOT_EXIST);
        }
        SysUser sysUser = new SysUser();
        sysUser.setPassword(passwordEncoder.encode(sysUserEX.getMobile()));
        sysUser.setId(userId);
        updateById(sysUser);
        return userId;
    }

    @Override
    public void handlerUserArea() {
        List<SysUser> list = list();
        list.forEach((t) -> {
            String parentIds = feignAreaService.getParentIds(t.getAreaId());
            SysUser sysUser = new SysUser();
            sysUser.setAllAreaIds(parentIds + "," + t.getAreaId());
            sysUser.setId(t.getId());
            updateById(sysUser);
        });
    }


    /**
     * @param newStatus 即将更改状态
     * @param oldStatus 本身状态
     */
    private void verifyStatus(Integer newStatus, Integer oldStatus) {
        //2者一致,说明状态错误
        if (oldStatus.equals(newStatus)) {
            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "审核状态错误");
        }
        //已经审核不能在审核
        if (oldStatus == AuditStatusEnum.PASSED.getCode()) {
            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构已审核");
        }

//        //0状态说明机构还没提交
//        if (oldStatus != AuditStatusEnum.TO_AUDIT.getCode()) {
//            throw new BusinessException(UserExceptionEnum.AUDIT_ERROR.getCode(), "该机构暂未提交审核");
//        }
    }

    public void insertAuditLog(UserOrganAuditDTO userOrganAuditDTO) {
        SysAuditLog bean = new SysAuditLog();
        bean.setAuditStatus(userOrganAuditDTO.getAuditStatus());
        bean.setAuditTime(LocalDateTime.now());
        bean.setType(UserTypeEnum.ORGAN.getCode());
        bean.setUserId(userOrganAuditDTO.getUserId());
        bean.setRemarks(userOrganAuditDTO.getRemarks());
        bean.setAuditor(UserUtil.getLoginUser().getUserId());
        auditLogService.save(bean);
    }

    /**
     * 验证手机号码是否重复
     *
     * @param mobile 手机号码
     * @param userId 用户uid,修改的时候排除当前用户uid
     */
    public void verifyAccount(String mobile, Long userId) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getMobile, mobile);
        if (userId != null && userId > 0) {
            queryWrapper.lambda().notIn(SysUser::getId, userId);
        }
        SysUser sysUser = getOne(queryWrapper);
        if (sysUser != null) {
            throw new BusinessException(UserExceptionEnum.USER_EXIST_MOBILE);
        }
    }

    private void verifyMobile(String mobile) {
        if (!PhoneUtils.isPhone(mobile)) {
            throw new BusinessException(UserExceptionEnum.MOBILE_FORMAT_ERROR);
        }
    }

    /**
     * 生成流水号
     *
     * @return
     */
    private String generateOrderNo() {
        Snowflake snowflake = IdUtil.getSnowflake(1, 2);
        return "ORG" + snowflake.nextIdStr();
    }
}
